<template>
  <div>
    <p>ts 基础知识</p>
    <p>泛型创建的res:{{ res }}</p>
    <p>箭头函数泛型创建的Name:{{ liming }}</p>
    <p>枚举颜色{{ ColorGreen }}</p>
    <p>接口创建的对象{{ LiMing }}</p>
    <p>接口创建的数组{{ myStr }}</p>
    <p>接口创建的继承对象{{ xiaoDong }}</p>
    <p>类结合接口创建的继承对象{{ wang }} {{ wang.sayHello() }}</p>
    <p>接口继承类创建dog {{ Dog }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const isDone: boolean = false;
    const num: number = 0;
    const str: string = "";
    const arr: number[] = [1, 2, 3, 4];
    const arr2: Array<number> = [1, 2, 3, 4];
    function ide<T>(arg: T) {
      return arg;
    }
    let res = ide<string>("str");
    const Name = <T>(name: T) => {
      return name;
    };
    let liming = Name<string>("Li-Ming");
    const Tuple: [number, string, boolean] = [1, "4", false];
    enum Color {
      Red = "red",
      Green = "green",
      Blue = "blue",
    }
    // 类型断言
    const ColorGreen: Color = Color.Green;
    let X = <string>"hello";
    const fuc = (): void => {
      //void 表示没有返回值
    };
    let u: undefined = undefined;
    let n: null = null;
    // 接口
    interface Person {
      readonly name: string;
      readonly children?: Person;
    }
    let LiMing: Person = {
      name: "LiMing",
      children: { name: "xiaohong" },
    };

    interface student extends Person {
      score?: number;
      grade?: number;
      sayHello?(): string;
    }

    const xiaoDong: student = {
      name: "xiaoDong",
      score: 100,
      grade: 2,
    };

    interface StringArray {
      [index: number]: string;
    }

    let myArray: StringArray;
    myArray = ["Bob", "Fred"];

    let myStr: string = myArray[0];
    // 类
    interface ClockInterface {
      currentTime: Date;
    }

    class Student implements student {
      name: string;
      score: number;
      grade: number;
      constructor(name: string) {
        this.name = name;
        this.score = 100;
        this.grade = 3;
      }
      sayHello(): string {
        return `Hello, I'm ${this.name}`;
      }
    }

    const wang = new Student("wang");

    // 接口继承类
    class Animal {
      year: number;
      constructor(year: number) {
        this.year = year;
      }
    }
    interface dog extends Animal {
      settings: {
        [key: string]: string | number;
      };
      applySettings?(): void;
      sayHello(): void;
    }
    let Dog: dog = {
      year: 12,
      settings: {
        color: "red",
        size: 10,
      },
      sayHello() {
        console.log("nihao2");
      },
    };

    function add(x: number, y: number): number {
      return x + y;
    }

    const add2 = (x: number, y: number): number => {
      return x + y;
    };

    let result: (x: number, y: number) => number = (x: number, y: number): number => {
      return x + y;
    };

    function sum(firNum: number, ...numbers: number[]): number {
      return firNum + numbers.reduce((total, num) => total + num, 0);
    }

    // console.log(result(1, 2));

    function buildName(firstName: string, ...restOfName: string[]) {
      return firstName + " " + restOfName.join(" ");
    }

    let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
    // console.log(employeeName);

    let a = sum(1, 2, 3, 4);
    // console.log(a);

    // 泛型
    // <T>(name: T) => {
    function f<T>(name: T): T {
      // console.log((name as string).length);
      return name;
    }
    let name = f<string>("LUO");
    // let N = f<number>(3);
    // console.log(name);

    class GenericNumber<T> {
      zeroValue: T | undefined;
      add: ((x: T, y: T) => T) | undefined;
    }

    let myGenericNumber = new GenericNumber<number>();
    myGenericNumber.zeroValue = 0;
    myGenericNumber.add = function (x, y) {
      return x + y;
    };
    // console.log(myGenericNumber.add(1, 5));

    interface Stu<T> {
      name: T;
      school: T;
    }
    let XX: Stu<string> = { name: "XX", school: "实验小学" };
    // console.log(XX);

    // 类型
    interface A {
      str: string;
    }

    interface B {
      str: undefined | string;
    }

    let name1: A & B = { str: "hahah" };
    // console.log(name1);

    type StringProperties<T> = {
      [K in keyof T & string as T[K] extends string ? K : never]: T[K];
    };
    interface MyObject {
      name: string;
      age: number;
      address: string;
    }
    type StringPropsObject = StringProperties<MyObject>;
    // type StringPropsObject = {
    //   name: string;
    //   address: string;
    // };

    interface OriginalType {
      a: number;
      b: string;
    }
    type MappedType = { [P in keyof OriginalType]: boolean };

    function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
      return obj[key];
    }
    interface Car {
      brand: string;
      model: string;
      year: number;
    }
    const myCar: Car = { brand: "Toyota", model: "Corolla", year: 2020 };
    const brand = getProperty(myCar, "brand");
    // brand的类型是string
    // console.log(brand);

    let list = [4, 5, 6];

    for (let i in list) {
      // console.log(i); // "0", "1", "2",
    }

    interface Box {
      height: number;
      width: number;
    }

    interface Box {
      scale: number;
    }

    let box: Box = { height: 5, width: 6, scale: 10 };

    function classDecorator(constructor: Function) {
      // console.log("Class decorator is called.");
    }
    @classDecorator
    class MyClass {
      constructor() {
        // console.log("MyClass constructor is called.");
      }
    }
    let classDecorator2 = new MyClass();
    // console.log("classDecorator2", classDecorator2);

    // mixin
    function LoggingMixin<TBase extends new (...args: any[]) => {}>(Base: TBase) {
      return class LoggingClass extends Base {
        log(message: string) {
          console.log(`Base log`, message);
        }
      };
    }

    class User {
      constructor(public name: string) {}
    }
    // 使用mixin为User类添加功能
    const LoggedUser = LoggingMixin(User);
    const user = new LoggedUser("Alice");
    user.log("User logged in");

    return {
      res,
      liming,
      ColorGreen,
      LiMing,
      myStr,
      xiaoDong,
      wang,
      Dog,
    };
  },
});
</script>
